home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gxipixel.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  24.9 KB  |  813 lines

  1. /* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gxipixel.c,v 1.2 2000/09/19 19:00:38 lpd Exp $ */
  20. /* Common code for ImageType 1 and 4 initialization */
  21. #include "gx.h"
  22. #include "math_.h"
  23. #include "memory_.h"
  24. #include "gpcheck.h"
  25. #include "gscdefs.h"        /* for image class table */
  26. #include "gserrors.h"
  27. #include "gsstruct.h"
  28. #include "gsutil.h"
  29. #include "gxfixed.h"
  30. #include "gxfrac.h"
  31. #include "gxarith.h"
  32. #include "gxmatrix.h"
  33. #include "gsccolor.h"
  34. #include "gspaint.h"
  35. #include "gzstate.h"
  36. #include "gxdevice.h"
  37. #include "gzpath.h"
  38. #include "gzcpath.h"
  39. #include "gxdevmem.h"
  40. #include "gximage.h"
  41. #include "gxiparam.h"
  42. #include "gdevmrop.h"
  43.  
  44. /* Structure descriptors */
  45. private_st_gx_image_enum();
  46.  
  47. /* Image class procedures */
  48. extern_gx_image_class_table();
  49.  
  50. /* Enumerator procedures */
  51. private const gx_image_enum_procs_t image1_enum_procs = {
  52.     gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
  53. };
  54.  
  55. /* GC procedures */
  56. private 
  57. ENUM_PTRS_WITH(image_enum_enum_ptrs, gx_image_enum *eptr)
  58. {
  59.     int bps;
  60.     gs_ptr_type_t ret;
  61.  
  62.     /* Enumerate the used members of clues.dev_color. */
  63.     index -= gx_image_enum_num_ptrs;
  64.     bps = eptr->unpack_bps;
  65.     if (eptr->spp != 1)
  66.     bps = 8;
  67.     else if (bps > 8 || eptr->unpack == sample_unpack_copy)
  68.     bps = 1;
  69.     if (index >= (1 << bps) * st_device_color_max_ptrs)        /* done */
  70.     return 0;
  71.     ret = ENUM_USING(st_device_color,
  72.              &eptr->clues[(index / st_device_color_max_ptrs) *
  73.                   (255 / ((1 << bps) - 1))].dev_color,
  74.              sizeof(eptr->clues[0].dev_color),
  75.              index % st_device_color_max_ptrs);
  76.     if (ret == 0)        /* don't stop early */
  77.     ENUM_RETURN(0);
  78.     return ret;
  79. }
  80. #define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
  81. gx_image_enum_do_ptrs(e1)
  82. #undef e1
  83. ENUM_PTRS_END
  84. private RELOC_PTRS_WITH(image_enum_reloc_ptrs, gx_image_enum *eptr)
  85. {
  86.     int i;
  87.  
  88. #define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
  89.     gx_image_enum_do_ptrs(r1)
  90. #undef r1
  91.     {
  92.     int bps = eptr->unpack_bps;
  93.  
  94.     if (eptr->spp != 1)
  95.         bps = 8;
  96.     else if (bps > 8 || eptr->unpack == sample_unpack_copy)
  97.         bps = 1;
  98.     for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
  99.         RELOC_USING(st_device_color,
  100.             &eptr->clues[i].dev_color, sizeof(gx_device_color));
  101.     }
  102. }
  103. RELOC_PTRS_END
  104.  
  105. /* Forward declarations */
  106. private int color_draws_b_w(P2(gx_device * dev,
  107.                    const gx_drawing_color * pdcolor));
  108. private void image_init_map(P3(byte * map, int map_size, const float *decode));
  109. private void image_init_colors(P9(gx_image_enum * penum, int bps, int spp,
  110.                   gs_image_format_t format,
  111.                   const float *decode,
  112.                   const gs_imager_state * pis, gx_device * dev,
  113.                   const gs_color_space * pcs, bool * pdcb));
  114.  
  115. /* Procedures for unpacking the input data into bytes or fracs. */
  116. /*extern SAMPLE_UNPACK_PROC(sample_unpack_copy); *//* declared above */
  117.  
  118. /*
  119.  * Do common initialization for processing an ImageType 1 or 4 image.
  120.  * Allocate the enumerator and fill in the following members:
  121.  *    rect
  122.  */
  123. int
  124. gx_image_enum_alloc(const gs_image_common_t * pic,
  125.             const gs_int_rect * prect, gs_memory_t * mem,
  126.             gx_image_enum **ppenum)
  127. {
  128.     const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
  129.     int width = pim->Width, height = pim->Height;
  130.     int bpc = pim->BitsPerComponent;
  131.     gx_image_enum *penum;
  132.  
  133.     if (width < 0 || height < 0)
  134.     return_error(gs_error_rangecheck);
  135.     switch (pim->format) {
  136.     case gs_image_format_chunky:
  137.     case gs_image_format_component_planar:
  138.     switch (bpc) {
  139.     case 1: case 2: case 4: case 8: case 12: break;
  140.     default: return_error(gs_error_rangecheck);
  141.     }
  142.     break;
  143.     case gs_image_format_bit_planar:
  144.     if (bpc < 1 || bpc > 8)
  145.         return_error(gs_error_rangecheck);
  146.     }
  147.     if (prect) {
  148.     if (prect->p.x < 0 || prect->p.y < 0 ||
  149.         prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
  150.         prect->q.x > width || prect->q.y > height
  151.         )
  152.         return_error(gs_error_rangecheck);
  153.     }
  154.     penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
  155.                 "gx_default_begin_image");
  156.     if (penum == 0)
  157.     return_error(gs_error_VMerror);
  158.     if (prect) {
  159.     penum->rect.x = prect->p.x;
  160.     penum->rect.y = prect->p.y;
  161.     penum->rect.w = prect->q.x - prect->p.x;
  162.     penum->rect.h = prect->q.y - prect->p.y;
  163.     } else {
  164.     penum->rect.x = 0, penum->rect.y = 0;
  165.     penum->rect.w = width, penum->rect.h = height;
  166.     }
  167. #ifdef DEBUG
  168.     if (gs_debug_c('b')) {
  169.     dlprintf2("[b]Image: w=%d h=%d", width, height);
  170.     if (prect)
  171.         dprintf4(" ((%d,%d),(%d,%d))",
  172.              prect->p.x, prect->p.y, prect->q.x, prect->q.y);
  173.     }
  174. #endif
  175.     *ppenum = penum;
  176.     return 0;
  177. }
  178.  
  179. /*
  180.  * Finish initialization for processing an ImageType 1 or 4 image.
  181.  * Assumes the following members of *penum are set in addition to those
  182.  * set by gx_image_enum_alloc:
  183.  *    alpha, use_mask_color, mask_color (if use_mask_color is true),
  184.  *    masked, adjust
  185.  */
  186. int
  187. gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
  188.             const gs_matrix *pmat, const gs_image_common_t * pic,
  189.         const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
  190.         gs_memory_t * mem, gx_image_enum *penum)
  191. {
  192.     const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
  193.     gs_image_format_t format = pim->format;
  194.     const int width = pim->Width;
  195.     const int height = pim->Height;
  196.     const int bps = pim->BitsPerComponent;
  197.     bool masked = penum->masked;
  198.     const float *decode = pim->Decode;
  199.     gs_matrix mat;
  200.     int index_bps;
  201.     const gs_color_space *pcs = pim->ColorSpace;
  202.     gs_logical_operation_t lop = (pis ? pis->log_op : lop_default);
  203.     int code;
  204.     int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
  205.     int spp, nplanes, spread;
  206.     uint bsize;
  207.     byte *buffer;
  208.     fixed mtx, mty;
  209.     gs_fixed_point row_extent, col_extent, x_extent, y_extent;
  210.     bool device_color;
  211.     gs_fixed_rect obox, cbox;
  212.  
  213.     if (pmat == 0)
  214.     pmat = &ctm_only(pis);
  215.     if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
  216.     (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0
  217.     ) {
  218.     gs_free_object(mem, penum, "gx_default_begin_image");
  219.     return code;
  220.     }
  221.     penum->matrix = mat;
  222.     if_debug6('b', " [%g %g %g %g %g %g]\n",
  223.           mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
  224.     /* following works for 1, 2, 4, 8, 12 */
  225.     index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
  226.     mtx = float2fixed(mat.tx);
  227.     mty = float2fixed(mat.ty);
  228.     row_extent.x = float2fixed(width * mat.xx + mat.tx) - mtx;
  229.     row_extent.y =
  230.     (is_fzero(mat.xy) ? fixed_0 :
  231.      float2fixed(width * mat.xy + mat.ty) - mty);
  232.     col_extent.x =
  233.     (is_fzero(mat.yx) ? fixed_0 :
  234.      float2fixed(height * mat.yx + mat.tx) - mtx);
  235.     col_extent.y = float2fixed(height * mat.yy + mat.ty) - mty;
  236.     gx_image_enum_common_init((gx_image_enum_common_t *)penum,
  237.                   (const gs_data_image_t *)pim,
  238.                   &image1_enum_procs, dev,
  239.                   (masked ? 1 : cs_num_components(pcs)),
  240.                   format);
  241.     if (penum->rect.w == width && penum->rect.h == height) {
  242.     x_extent = row_extent;
  243.     y_extent = col_extent;
  244.     } else {
  245.     int rw = penum->rect.w, rh = penum->rect.h;
  246.  
  247.     x_extent.x = float2fixed(rw * mat.xx + mat.tx) - mtx;
  248.     x_extent.y =
  249.         (is_fzero(mat.xy) ? fixed_0 :
  250.          float2fixed(rw * mat.xy + mat.ty) - mty);
  251.     y_extent.x =
  252.         (is_fzero(mat.yx) ? fixed_0 :
  253.          float2fixed(rh * mat.yx + mat.tx) - mtx);
  254.     y_extent.y = float2fixed(rh * mat.yy + mat.ty) - mty;
  255.     }
  256.     if (masked) {    /* This is imagemask. */
  257.     if (bps != 1 || pcs != NULL || penum->alpha ||
  258.         !((decode[0] == 0.0 && decode[1] == 1.0) ||
  259.           (decode[0] == 1.0 && decode[1] == 0.0))
  260.         ) {
  261.         gs_free_object(mem, penum, "gx_default_begin_image");
  262.         return_error(gs_error_rangecheck);
  263.     }
  264.     /* Initialize color entries 0 and 255. */
  265.     color_set_pure(&penum->icolor0, gx_no_color_index);
  266.     penum->icolor1 = *pdcolor;
  267.     memcpy(&penum->map[0].table.lookup4x1to32[0],
  268.            (decode[0] == 0 ? lookup4x1to32_inverted :
  269.         lookup4x1to32_identity),
  270.            16 * 4);
  271.     penum->map[0].decoding = sd_none;
  272.     spp = 1;
  273.     lop = rop3_know_S_0(lop);
  274.     } else {            /* This is image, not imagemask. */
  275.     const gs_color_space_type *pcst = pcs->type;
  276.     int b_w_color;
  277.  
  278.     spp = cs_num_components(pcs);
  279.     if (spp < 0) {        /* Pattern not allowed */
  280.         gs_free_object(mem, penum, "gx_default_begin_image");
  281.         return_error(gs_error_rangecheck);
  282.     }
  283.     if (penum->alpha)
  284.         ++spp;
  285.     /* Use a less expensive format if possible. */
  286.     switch (format) {
  287.     case gs_image_format_bit_planar:
  288.         if (bps > 1)
  289.         break;
  290.         format = gs_image_format_component_planar;
  291.     case gs_image_format_component_planar:
  292.         if (spp == 1)
  293.         format = gs_image_format_chunky;
  294.     default:        /* chunky */
  295.         break;
  296.     }
  297.     device_color = (*pcst->concrete_space) (pcs, pis) == pcs;
  298.     image_init_colors(penum, bps, spp, format, decode, pis, dev,
  299.               pcs, &device_color);
  300.     /* Try to transform non-default RasterOps to something */
  301.     /* that we implement less expensively. */
  302.     if (!pim->CombineWithColor)
  303.         lop = rop3_know_T_0(lop) & ~lop_T_transparent;
  304.     else {
  305.         if (rop3_uses_T(lop))
  306.         switch (color_draws_b_w(dev, pdcolor)) {
  307.             case 0:
  308.             lop = rop3_know_T_0(lop);
  309.             break;
  310.             case 1:
  311.             lop = rop3_know_T_1(lop);
  312.             break;
  313.             default:
  314.             ;
  315.         }
  316.     }
  317.     if (lop != rop3_S &&    /* if best case, no more work needed */
  318.         !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
  319.         (b_w_color =
  320.          color_draws_b_w(dev, &penum->icolor0)) >= 0 &&
  321.         color_draws_b_w(dev, &penum->icolor1) == (b_w_color ^ 1)
  322.         ) {
  323.         if (b_w_color) {    /* Swap the colors and invert the RasterOp source. */
  324.         gx_device_color dcolor;
  325.  
  326.         dcolor = penum->icolor0;
  327.         penum->icolor0 = penum->icolor1;
  328.         penum->icolor1 = dcolor;
  329.         lop = rop3_invert_S(lop);
  330.         }
  331.         /*
  332.          * At this point, we know that the source pixels
  333.          * correspond directly to the S input for the raster op,
  334.          * i.e., icolor0 is black and icolor1 is white.
  335.          */
  336.         switch (lop) {
  337.         case rop3_D & rop3_S:
  338.             /* Implement this as an inverted mask writing 0s. */
  339.             penum->icolor1 = penum->icolor0;
  340.             /* (falls through) */
  341.         case rop3_D | rop3_not(rop3_S):
  342.             /* Implement this as an inverted mask writing 1s. */
  343.             memcpy(&penum->map[0].table.lookup4x1to32[0],
  344.                lookup4x1to32_inverted, 16 * 4);
  345.           rmask:    /* Fill in the remaining parameters for a mask. */
  346.             penum->masked = masked = true;
  347.             color_set_pure(&penum->icolor0, gx_no_color_index);
  348.             penum->map[0].decoding = sd_none;
  349.             lop = rop3_T;
  350.             break;
  351.         case rop3_D & rop3_not(rop3_S):
  352.             /* Implement this as a mask writing 0s. */
  353.             penum->icolor1 = penum->icolor0;
  354.             /* (falls through) */
  355.         case rop3_D | rop3_S:
  356.             /* Implement this as a mask writing 1s. */
  357.             memcpy(&penum->map[0].table.lookup4x1to32[0],
  358.                lookup4x1to32_identity, 16 * 4);
  359.             goto rmask;
  360.         default:
  361.             ;
  362.         }
  363.     }
  364.     }
  365.     penum->device_color = device_color;
  366.     /*
  367.      * Adjust width upward for unpacking up to 7 trailing bits in
  368.      * the row, plus 1 byte for end-of-run, plus up to 7 leading
  369.      * bits for data_x offset within a packed byte.
  370.      */
  371.     bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
  372.     buffer = gs_alloc_bytes(mem, bsize, "image buffer");
  373.     if (buffer == 0) {
  374.     gs_free_object(mem, penum, "gx_default_begin_image");
  375.     return_error(gs_error_VMerror);
  376.     }
  377.     penum->bps = bps;
  378.     penum->unpack_bps = bps;
  379.     penum->log2_xbytes = log2_xbytes;
  380.     penum->spp = spp;
  381.     switch (format) {
  382.     case gs_image_format_chunky:
  383.     nplanes = 1;
  384.     spread = 1 << log2_xbytes;
  385.     break;
  386.     case gs_image_format_component_planar:
  387.     nplanes = spp;
  388.     spread = spp << log2_xbytes;
  389.     break;
  390.     case gs_image_format_bit_planar:
  391.     nplanes = spp * bps;
  392.     spread = spp << log2_xbytes;
  393.     break;
  394.     default:
  395.     /* No other cases are possible (checked by gx_image_enum_alloc). */
  396.     return_error(gs_error_Fatal);
  397.     }
  398.     penum->num_planes = nplanes;
  399.     penum->spread = spread;
  400.     /*
  401.      * If we're asked to interpolate in a partial image, we have to
  402.      * assume that the client either really only is interested in
  403.      * the given sub-image, or else is constructing output out of
  404.      * overlapping pieces.
  405.      */
  406.     penum->interpolate = pim->Interpolate;
  407.     penum->x_extent = x_extent;
  408.     penum->y_extent = y_extent;
  409.     penum->posture =
  410.     ((x_extent.y | y_extent.x) == 0 ? image_portrait :
  411.      (x_extent.x | y_extent.y) == 0 ? image_landscape :
  412.      image_skewed);
  413.     penum->pis = pis;
  414.     penum->pcs = pcs;
  415.     penum->memory = mem;
  416.     penum->buffer = buffer;
  417.     penum->buffer_size = bsize;
  418.     penum->line = 0;
  419.     penum->line_size = 0;
  420.     penum->use_rop = lop != (masked ? rop3_T : rop3_S);
  421. #ifdef DEBUG
  422.     if (gs_debug_c('*')) {
  423.     if (penum->use_rop)
  424.         dprintf1("[%03x]", lop);
  425.     dprintf5("%c%d%c%dx%d ",
  426.          (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
  427.          bps,
  428.          (penum->posture == image_portrait ? ' ' :
  429.           penum->posture == image_landscape ? 'L' : 'T'),
  430.          width, height);
  431.     }
  432. #endif
  433.     penum->slow_loop = 0;
  434.     if (pcpath == 0) {
  435.     (*dev_proc(dev, get_clipping_box)) (dev, &obox);
  436.     cbox = obox;
  437.     penum->clip_image = 0;
  438.     } else
  439.     penum->clip_image =
  440.         (gx_cpath_outer_box(pcpath, &obox) |    /* not || */
  441.          gx_cpath_inner_box(pcpath, &cbox) ?
  442.          0 : image_clip_region);
  443.     penum->clip_outer = obox;
  444.     penum->clip_inner = cbox;
  445.     penum->log_op = rop3_T;    /* rop device takes care of this */
  446.     penum->clip_dev = 0;    /* in case we bail out */
  447.     penum->rop_dev = 0;        /* ditto */
  448.     penum->scaler = 0;        /* ditto */
  449.     /*
  450.      * If all four extrema of the image fall within the clipping
  451.      * rectangle, clipping is never required.  When making this check,
  452.      * we must carefully take into account the fact that we only care
  453.      * about pixel centers.
  454.      */
  455.     {
  456.     fixed
  457.         epx = min(row_extent.x, 0) + min(col_extent.x, 0),
  458.         eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
  459.         epy = min(row_extent.y, 0) + min(col_extent.y, 0),
  460.         eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
  461.  
  462.     {
  463.         int hwx, hwy;
  464.  
  465.         switch (penum->posture) {
  466.         case image_portrait:
  467.             hwx = width, hwy = height;
  468.             break;
  469.         case image_landscape:
  470.             hwx = height, hwy = width;
  471.             break;
  472.         default:
  473.             hwx = hwy = 0;
  474.         }
  475.         /*
  476.          * If the image is only 1 sample wide or high,
  477.          * and is less than 1 device pixel wide or high,
  478.          * move it slightly so that it covers pixel centers.
  479.          * This is a hack to work around a bug in some old
  480.          * versions of TeX/dvips, which use 1-bit-high images
  481.          * to draw horizontal and vertical lines without
  482.          * positioning them properly.
  483.          */
  484.         if (hwx == 1 && eqx - epx < fixed_1) {
  485.         fixed diff =
  486.         arith_rshift_1(row_extent.x + col_extent.x);
  487.  
  488.         mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
  489.         }
  490.         if (hwy == 1 && eqy - epy < fixed_1) {
  491.         fixed diff =
  492.         arith_rshift_1(row_extent.y + col_extent.y);
  493.  
  494.         mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
  495.         }
  496.     }
  497.     if_debug5('b', "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
  498.           (masked? "masked, " : ""), spp, bps,
  499.           fixed2float(mtx), fixed2float(mty));
  500.     if_debug9('b',
  501.           "[b]   cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
  502.           fixed2float(cbox.p.x), fixed2float(cbox.p.y),
  503.           fixed2float(cbox.q.x), fixed2float(cbox.q.y),
  504.           fixed2float(obox.p.x), fixed2float(obox.p.y),
  505.           fixed2float(obox.q.x), fixed2float(obox.q.y),
  506.           penum->clip_image);
  507.     dda_init(penum->dda.row.x, mtx, col_extent.x, height);
  508.     dda_init(penum->dda.row.y, mty, col_extent.y, height);
  509.     if (penum->rect.y) {
  510.         dda_advance(penum->dda.row.x, penum->rect.y);
  511.         dda_advance(penum->dda.row.y, penum->rect.y);
  512.     }
  513.     penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
  514.     penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
  515.     dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
  516.     dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
  517.     if (penum->rect.x) {
  518.         dda_advance(penum->dda.strip.x, penum->rect.x);
  519.         dda_advance(penum->dda.strip.y, penum->rect.x);
  520.     } {
  521.         fixed ox = dda_current(penum->dda.strip.x);
  522.         fixed oy = dda_current(penum->dda.strip.y);
  523.  
  524.         if (!penum->clip_image)    /* i.e., not clip region */
  525.         penum->clip_image =
  526.             (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
  527.              image_clip_xmin : 0) +
  528.             (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
  529.              image_clip_xmax : 0) +
  530.             (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
  531.              image_clip_ymin : 0) +
  532.             (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
  533.              image_clip_ymax : 0);
  534.     }
  535.     }
  536.     penum->y = 0;
  537.     penum->used.x = 0;
  538.     penum->used.y = 0;
  539.     {
  540.     static const sample_unpack_proc_t procs[4] = {
  541.         sample_unpack_1, sample_unpack_2,
  542.         sample_unpack_4, sample_unpack_8
  543.     };
  544.     int i;
  545.  
  546.     if (index_bps == 4) {
  547.         if ((penum->unpack = sample_unpack_12_proc) == 0) {        /* 12-bit samples are not supported. */
  548.         gx_default_end_image(dev,
  549.                      (gx_image_enum_common_t *) penum,
  550.                      false);
  551.         return_error(gs_error_rangecheck);
  552.         }
  553.     } else {
  554.         penum->unpack = procs[index_bps];
  555.         if_debug1('b', "[b]unpack=%d\n", bps);
  556.     }
  557.     /* Set up pixel0 for image class procedures. */
  558.     penum->dda.pixel0 = penum->dda.strip;
  559.     for (i = 0; i < gx_image_class_table_count; ++i)
  560.         if ((penum->render = gx_image_class_table[i](penum)) != 0)
  561.         break;
  562.     if (i == gx_image_class_table_count) {
  563.         /* No available class can handle this image. */
  564.         gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
  565.                  false);
  566.         return_error(gs_error_rangecheck);
  567.     }
  568.     }
  569.     if (penum->clip_image && pcpath) {    /* Set up the clipping device. */
  570.     gx_device_clip *cdev =
  571.         gs_alloc_struct(mem, gx_device_clip,
  572.                 &st_device_clip, "image clipper");
  573.  
  574.     if (cdev == 0) {
  575.         gx_default_end_image(dev,
  576.                  (gx_image_enum_common_t *) penum,
  577.                  false);
  578.         return_error(gs_error_VMerror);
  579.     }
  580.     gx_make_clip_translate_device(cdev, gx_cpath_list(pcpath), 0, 0, mem);
  581.     gx_device_retain((gx_device *)cdev, true); /* will free explicitly */
  582.     gx_device_set_target((gx_device_forward *)cdev, dev);
  583.     (*dev_proc(cdev, open_device)) ((gx_device *) cdev);
  584.     penum->clip_dev = cdev;
  585.     }
  586.     if (penum->use_rop) {    /* Set up the RasterOp source device. */
  587.     gx_device_rop_texture *rtdev;
  588.  
  589.     code = gx_alloc_rop_texture_device(&rtdev, mem,
  590.                        "image RasterOp");
  591.     if (code < 0) {
  592.         gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
  593.                  false);
  594.         return code;
  595.     }
  596.     gx_make_rop_texture_device(rtdev,
  597.                    (penum->clip_dev != 0 ?
  598.                     (gx_device *) penum->clip_dev :
  599.                     dev), lop, pdcolor);
  600.     penum->rop_dev = rtdev;
  601.     }
  602.     return 0;
  603. }
  604.  
  605. /* If a drawing color is black or white, return 0 or 1 respectively, */
  606. /* otherwise return -1. */
  607. private int
  608. color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
  609. {
  610.     if (color_is_pure(pdcolor)) {
  611.     gx_color_value rgb[3];
  612.  
  613.     (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
  614.                      rgb);
  615.     if (!(rgb[0] | rgb[1] | rgb[2]))
  616.         return 0;
  617.     if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
  618.         return 1;
  619.     }
  620.     return -1;
  621. }
  622.  
  623. /* Initialize the color mapping tables for a non-mask image. */
  624. private void
  625. image_init_colors(gx_image_enum * penum, int bps, int spp,
  626.           gs_image_format_t format, const float *decode /*[spp*2] */ ,
  627.           const gs_imager_state * pis, gx_device * dev,
  628.           const gs_color_space * pcs, bool * pdcb)
  629. {
  630.     int ci;
  631.     static const float default_decode[] = {
  632.     0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
  633.     };
  634.  
  635.     /* Initialize the color table */
  636.  
  637. #define ictype(i)\
  638.   penum->clues[i].dev_color.type
  639.     switch ((spp == 1 ? bps : 8)) {
  640.     case 8:        /* includes all color images */
  641.         {
  642.         register gx_image_clue *pcht = &penum->clues[0];
  643.         register int n = 64;
  644.  
  645.         do {
  646.             pcht[0].dev_color.type =
  647.             pcht[1].dev_color.type =
  648.             pcht[2].dev_color.type =
  649.             pcht[3].dev_color.type =
  650.             gx_dc_type_none;
  651.             pcht[0].key = pcht[1].key =
  652.             pcht[2].key = pcht[3].key = 0;
  653.             pcht += 4;
  654.         }
  655.         while (--n > 0);
  656.         penum->clues[0].key = 1;    /* guarantee no hit */
  657.         break;
  658.         }
  659.     case 4:
  660.         ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
  661.         ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
  662.         ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
  663.         ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
  664.         gx_dc_type_none;
  665.         /* falls through */
  666.     case 2:
  667.         ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
  668. #undef ictype
  669.     }
  670.  
  671.     /* Initialize the maps from samples to intensities. */
  672.  
  673.     for (ci = 0; ci < spp; ci++) {
  674.     sample_map *pmap = &penum->map[ci];
  675.  
  676.     /* If the decoding is [0 1] or [1 0], we can fold it */
  677.     /* into the expansion of the sample values; */
  678.     /* otherwise, we have to use the floating point method. */
  679.  
  680.     const float *this_decode = &decode[ci * 2];
  681.     const float *map_decode;    /* decoding used to */
  682.                     /* construct the expansion map */
  683.     const float *real_decode;    /* decoding for expanded samples */
  684.  
  685.     bool no_decode;
  686.  
  687.     map_decode = real_decode = this_decode;
  688.     if (map_decode[0] == 0.0 && map_decode[1] == 1.0)
  689.         no_decode = true;
  690.     else if (map_decode[0] == 1.0 && map_decode[1] == 0.0 && bps <= 8) {
  691.         no_decode = true;
  692.         real_decode = default_decode;
  693.     } else {
  694.         no_decode = false;
  695.         *pdcb = false;
  696.         map_decode = default_decode;
  697.     }
  698.     if (bps > 2 || format != gs_image_format_chunky) {
  699.         if (bps <= 8)
  700.         image_init_map(&pmap->table.lookup8[0], 1 << bps,
  701.                    map_decode);
  702.     } else {        /* The map index encompasses more than one pixel. */
  703.         byte map[4];
  704.         register int i;
  705.  
  706.         image_init_map(&map[0], 1 << bps, map_decode);
  707.         switch (bps) {
  708.         case 1:
  709.             {
  710.             register bits32 *p = &pmap->table.lookup4x1to32[0];
  711.  
  712.             if (map[0] == 0 && map[1] == 0xff)
  713.                 memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
  714.             else if (map[0] == 0xff && map[1] == 0)
  715.                 memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
  716.             else
  717.                 for (i = 0; i < 16; i++, p++)
  718.                 ((byte *) p)[0] = map[i >> 3],
  719.                     ((byte *) p)[1] = map[(i >> 2) & 1],
  720.                     ((byte *) p)[2] = map[(i >> 1) & 1],
  721.                     ((byte *) p)[3] = map[i & 1];
  722.             }
  723.             break;
  724.         case 2:
  725.             {
  726.             register bits16 *p = &pmap->table.lookup2x2to16[0];
  727.  
  728.             for (i = 0; i < 16; i++, p++)
  729.                 ((byte *) p)[0] = map[i >> 2],
  730.                 ((byte *) p)[1] = map[i & 3];
  731.             }
  732.             break;
  733.         }
  734.     }
  735.     pmap->decode_base /* = decode_lookup[0] */  = real_decode[0];
  736.     pmap->decode_factor =
  737.         (real_decode[1] - real_decode[0]) /
  738.         (bps <= 8 ? 255.0 : (float)frac_1);
  739.     pmap->decode_max /* = decode_lookup[15] */  = real_decode[1];
  740.     if (no_decode) {
  741.         pmap->decoding = sd_none;
  742.         pmap->inverted = map_decode[0] != 0;
  743.     } else if (bps <= 4) {
  744.         int step = 15 / ((1 << bps) - 1);
  745.         int i;
  746.  
  747.         pmap->decoding = sd_lookup;
  748.         for (i = 15 - step; i > 0; i -= step)
  749.         pmap->decode_lookup[i] = pmap->decode_base +
  750.             i * (255.0 / 15) * pmap->decode_factor;
  751.     } else
  752.         pmap->decoding = sd_compute;
  753.     if (spp == 1) {        /* and ci == 0 *//* Pre-map entries 0 and 255. */
  754.         gs_client_color cc;
  755.  
  756.         cc.paint.values[0] = real_decode[0];
  757.         (*pcs->type->remap_color) (&cc, pcs, &penum->icolor0,
  758.                        pis, dev, gs_color_select_source);
  759.         cc.paint.values[0] = real_decode[1];
  760.         (*pcs->type->remap_color) (&cc, pcs, &penum->icolor1,
  761.                        pis, dev, gs_color_select_source);
  762.     }
  763.     }
  764.  
  765. }
  766. /* Construct a mapping table for sample values. */
  767. /* map_size is 2, 4, 16, or 256.  Note that 255 % (map_size - 1) == 0, */
  768. /* so the division 0xffffL / (map_size - 1) is always exact. */
  769. private void
  770. image_init_map(byte * map, int map_size, const float *decode)
  771. {
  772.     float min_v = decode[0];
  773.     float diff_v = decode[1] - min_v;
  774.  
  775.     if (diff_v == 1 || diff_v == -1) {    /* We can do the stepping with integers, without overflow. */
  776.     byte *limit = map + map_size;
  777.     uint value = min_v * 0xffffL;
  778.     int diff = diff_v * (0xffffL / (map_size - 1));
  779.  
  780.     for (; map != limit; map++, value += diff)
  781.         *map = value >> 8;
  782.     } else {            /* Step in floating point, with clamping. */
  783.     int i;
  784.  
  785.     for (i = 0; i < map_size; ++i) {
  786.         int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
  787.  
  788.         map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
  789.     }
  790.     }
  791. }
  792.  
  793. /*
  794.  * Scale a pair of mask_color values to match the scaling of each sample to
  795.  * a full byte, and complement and swap them if the map incorporates
  796.  * a Decode = [1 0] inversion.
  797.  */
  798. void
  799. gx_image_scale_mask_colors(gx_image_enum *penum, int component_index)
  800. {
  801.     uint scale = 255 / ((1 << penum->bps) - 1);
  802.     uint *values = &penum->mask_color.values[component_index * 2];
  803.     uint v0 = values[0] *= scale;
  804.     uint v1 = values[1] *= scale;
  805.  
  806.     if (penum->map[component_index].decoding == sd_none &&
  807.     penum->map[component_index].inverted
  808.     ) {
  809.     values[0] = 255 - v1;
  810.     values[1] = 255 - v0;
  811.     }
  812. }
  813.